package com.aldobucchi.ds.container.utils
{
	import flash.events.Event;
	
	import mx.collections.IList;
	import mx.events.CollectionEvent;
	
	import com.aldobucchi.core.dependency.DependencySpec;
	import com.aldobucchi.core.dependency.MXMLObjectWithDependenciesBase;
	import com.aldobucchi.ds.DataStructureEvent;
	import com.aldobucchi.ds.container.IRContainer;
	import com.aldobucchi.x.flash.events.EventListenerSpec;



	/**
	 * 
	 * 
	 * TODO: optimize by inspecting the events
	 * @author aldo.bucchi@gmail.com
	 * 
	 */
	public class ItemInContainerFlag extends MXMLObjectWithDependenciesBase
	{

		
		////////////////////////////////////////
		// item
		////////////////////////////////////////
		
		private var itemSpec:DependencySpec = new DependencySpec( "item", "itemChanged" );
		[Bindable("itemChanged")]
		public function get item( ):*
		{
			return dh.getDependencyValue( itemSpec );
		}

		public function set item( v:* ):void
		{
			dh.setDependencyValue( itemSpec, v );
		}
		
		


		////////////////////////////////////////
		// container
		////////////////////////////////////////


		private var containerELS:Array = [
				
				// we cover both cases... mx.collections and ds ( data structures )
				new EventListenerSpec( CollectionEvent.COLLECTION_CHANGE, container_collectionChange, false, 0, true ),
				new EventListenerSpec( DataStructureEvent.CHANGE, container_dataStructureChange, false, 0, true )			
		
			];

		private var containerSpec:DependencySpec = new DependencySpec( "container", "containerChanged" );
		[Bindable("containerChanged")]
		/**
		 * 
		 * An Array, IList or IRContainer
		 * 
		 * @return 
		 * 
		 */		
		public function get container( ):*
		{
			return dh.getDependencyValue( containerSpec );
		}

		public function set container( v:* ):void
		{
			dh.setDependencyValue( containerSpec, v );
		}
		
		
		
		
		////////////////////////////////////////
		// isContained
		////////////////////////////////////////		
		
		private var _isContained:Boolean;
		[Bindable("change")]
		public function get isContained( ):Boolean
		{
			return _isContained;
		}
		
		
		
		
		
		
		
		
		
		private function refresh( ):void
		{
		
			setIsContained( testContainment() );
				
		}
		
		
		private function setIsContained( v:Boolean ):void
		{
			
			if ( _isContained == v )
				return;
				
			_isContained = v;
			
			if ( willTrigger( Event.CHANGE ) )
				dispatchEvent( new Event( Event.CHANGE ) );		
		
		}
		
		
		private function testContainment( ):Boolean
		{
		
			if ( item === undefined )
				return false;
				
			if ( container === undefined )
				return false;
				
			
			if ( container is Array )
			{
				return ( ( container as Array ).indexOf( item ) != -1 );
			}
			
			
			if ( container is IList )
			{
				return ( ( container as IList ).getItemIndex( item ) != -1 );			
			}	
				
		
			if ( container is IRContainer )
			{
				return ( ( container as IRContainer ).contains( item ) );
			}
		
			return false;
		}
		
		
		
		
		override protected function dependenciesUpdated( ):void
		{

			refresh( );	
		
		}
		
		
		
		private function container_collectionChange( event:CollectionEvent ):void
		{
		
			refresh( );
		
		}
		
		
		private function container_dataStructureChange( event:DataStructureEvent ):void
		{
		
			refresh( );
		
		}
		


		
	}
}